package com.tsing.common.utils;

import com.alibaba.fastjson.JSONObject;
import com.tsing.common.exceptions.BusinessException;
import com.tsing.common.exceptions.CommonException;
import com.tsing.common.vo.HttpResult;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class HttpClientUtil {

    @Autowired
    private static CloseableHttpClient httpClient;

    private static int connectTimeout = 5000;

    private static int connectionRequestTimeout = 1000;

    private static int socketTimeout = 5000;

    /**
     * 以get方式调用第三方接口
     */
    public static String doGet(String url, String token, Map<String, Object> params) {
        //创建HttpClient对象
        if (null == httpClient) {
            httpClient = HttpClientBuilder.create().build();
        }
        HttpGet httpGet = null;
        if (null != params && params.size() > 0) {
            try {
                URIBuilder uriBuilder = new URIBuilder(url);
                List<NameValuePair> list = new LinkedList<>();
                for (Map.Entry<String, Object> entry : params.entrySet()) {
                    list.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
                }
                uriBuilder.setParameters(list);
                httpGet = new HttpGet(uriBuilder.build());
            } catch (URISyntaxException e) {
                e.printStackTrace();
            }
        } else {
            httpGet = new HttpGet(url);
        }
        if (!StringUtils.isBlank(token)) {
            httpGet.setHeader("token", token);
        }
        RequestConfig build = RequestConfig.custom()
                .setConnectTimeout(connectTimeout).setConnectionRequestTimeout(connectionRequestTimeout)
                .setSocketTimeout(socketTimeout).build();
        httpGet.setConfig(build);
        try {
            HttpResponse response = httpClient.execute(httpGet);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                //返回json格式
                return EntityUtils.toString(response.getEntity());
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            httpGet.releaseConnection();
        }
        return null;
    }

    public static String doGetFile(String url, String filePath) {
        try {
            if (null == httpClient) {
                httpClient = HttpClientBuilder.create().build();
            }
            HttpPost uploadFile = new HttpPost(url);
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            File f = new File(filePath);
            //把文件加到HTTP的post请求中
            builder.addBinaryBody(
                    "code_file",
                    new FileInputStream(f),
                    ContentType.APPLICATION_OCTET_STREAM,
                    f.getName()
            );
            HttpEntity multipart = builder.build();
            uploadFile.setEntity(multipart);
            CloseableHttpResponse response = httpClient.execute(uploadFile);
            return EntityUtils.toString(response.getEntity(), "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 以post方式调用第三方接口
     */
    public static String doPost(String url, JSONObject json, String token) {
        if (null == httpClient) {
            httpClient = HttpClientBuilder.create().build();
        }
        HttpPost httpPost = new HttpPost(url);
        if (!StringUtils.isBlank(token)) {
            httpPost.addHeader("token", token);
        }
        RequestConfig build = RequestConfig.custom()
                .setConnectTimeout(connectTimeout).setConnectionRequestTimeout(connectionRequestTimeout)
                .setSocketTimeout(socketTimeout).build();
        httpPost.setConfig(build);
        try {
            StringEntity se = new StringEntity(json.toString(), Charset.forName("UTF-8"));
            se.setContentEncoding("UTF-8");
            se.setContentType("application/json");
            //设置请求参数
            httpPost.setEntity(se);
            HttpResponse response = httpClient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                //返回json格式
                return EntityUtils.toString(response.getEntity());
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //连接池使用的时候不能关闭连接，否则下次使用会抛异常 java.lang.IllegalStateException: Connection pool shut down
            httpPost.releaseConnection();
        }
        return null;
    }

    public static HttpResult doPostFile(String url, Map<String, File> fileParam, Map<String, Object> map) {
        if (null == httpClient) {
            httpClient = HttpClientBuilder.create().build();
        }
        HttpPost httpPost = new HttpPost(url);
        try {
            RequestConfig build = RequestConfig.custom()
                    .setConnectTimeout(connectTimeout).setConnectionRequestTimeout(connectionRequestTimeout)
                    .setSocketTimeout(socketTimeout).build();
            httpPost.setConfig(build);
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            if (fileParam != null) {
                //遍历图片并添加到MultipartEntity实体中
                for (Map.Entry<String, File> entry : fileParam.entrySet()) {
                    builder.addBinaryBody(entry.getKey(), new FileInputStream(entry.getValue()), ContentType.DEFAULT_BINARY, entry.getValue().getName());
                }
            }
            if (map != null) {
                for (Map.Entry<String, Object> entry : map.entrySet()) {
                    builder.addPart(entry.getKey(), new StringBody(entry.getValue().toString(), ContentType.create("text/plain", Consts.UTF_8)));
                }
            }
            HttpEntity entity = builder.build();// 生成 HTTP POST 实体
            httpPost.setEntity(entity);
            CloseableHttpResponse response = httpClient.execute(httpPost);
            return new HttpResult(response.getStatusLine().getStatusCode(),
                    EntityUtils.toString(response.getEntity(), "UTF-8"));
        } catch (Exception e) {
            throw new BusinessException(CommonException.Proxy.HTTPCLIENT_FILE_ERROR);
        } finally {
            httpPost.releaseConnection();
        }
    }

    public static URLConnection getGConnection(String url, String param) {
        URLConnection connection = null;
        BufferedReader in = null;
        try {
            String urlNameString = url + "?" + param;
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.out.println(key + "--->" + map.get(key));
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常！" + e);
            e.printStackTrace();
        }
        //使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return connection;
    }

}
